﻿using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class StoryAction_Queue : StoryAction
    {
        private List<StoryAction> _actions = new();
        private bool _isEnding;

        protected override bool OnInitialize(GameObject root, StoryActionData data)
        {
            base.OnInitialize(root, data);
            if (data is StoryActionData_Queue rQueue)
            {
                for (int i = 0; i < rQueue.actions.Count; i++)
                {
                    var nID = rQueue.actions[i];
                    var rConfig = StoryActionGlobal.Get(nID);
                    var rAction = StoryFactoryClient.GetAction(this.ui, root, rConfig.data);
                    if (rAction != null)
                    {
                        this._actions.Add(rAction);
                    }
                }
                return true;
            }
            return false;
        }
        
        protected override void OnBindDynamic(EStoryActionDynamicKey key, object value)
        {
            base.OnBindDynamic(key, value);
            for (int i = 0; i < this._actions.Count; i++)
            {
                this._actions[i].BindDynamic(key, value);
            }
        }
        
        protected override void OnBeforeStart()
        {
            base.OnBeforeStart();
            for (int i = 0; i < this._actions.Count; i++)
            {
                this._actions[i].BeforeStart();
            }
        }
        
        protected override async UniTask OnStart(CancellationToken cancel)
        {
            await base.OnStart(cancel);
            for (int i = 0; i < this._actions.Count && !this._isEnding; i++)
            {
                await this._actions[i].Start();
            }
        }

        protected override void OnUpdate(float dt)
        {
            base.OnUpdate(dt);
            for (int i = 0; i < this._actions.Count; i++)
            {
                this._actions[i].Update(dt);
            }
        }

        protected override void OnBeforeEnd()
        {
            base.OnBeforeStart();
            for (int i = 0; i < this._actions.Count; i++)
            {
                this._actions[i].BeforeEnd();
            }
        }
        
        protected override async UniTask OnEnd(CancellationToken cancel)
        {
            await base.OnEnd(cancel);
            this._isEnding = true;
            for (int i = 0; i < this._actions.Count; i++)
            {
                await this._actions[i].End();
            }
        }

        protected override void OnDispose()
        {
            base.OnDispose();
            for (int i = 0; i < this._actions.Count; i++)
            {
                this._actions[i].Dispose();
            }
            this._actions.Clear();
        }
        
        public override void OnReset()
        {
            base.OnReset();
            this._isEnding = false;
        }

        public override void Free()
        {
            ClassPool.Put(this);
        }
    }
}